﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Transactions;
using SD.Commons;
using SD.Commons.DataFilters;

namespace SD.DataAccess
{
    [Serializable]
    public class DepartmentDao : Department
    {
        /// <summary>
        /// Context object is used to duel with database
        /// </summary>
        [NonSerialized]
        private readonly ServiceDBDataContext _context =  new ServiceDBDataContext();
       
        /// <summary>
        /// FilterList method is used to filt data from database
        /// </summary>
        /// <param name="data">data</param>
        /// <param name="filter">filter</param>
        /// <returns>Departments</returns>
        private IQueryable<Department> FilterList(IQueryable<Department> data,DepartmentFilter filter)
        {
          //  data = data.Where(d => d.DirectorateId == filter.DirectorateId);
            if (filter.BeginningLetters != null)
            {
                data = data.Where(g => filter.BeginningLetters.Contains(g.DepartmentName[0].ToString()));
            }

            if (!filter.IncludeInactive)
            {
                data = data.Where(g => g.IsActive);
            }
            return data;
        }

        /// <summary>
        /// SortList method is used to sort a data list which is got from database
        /// </summary>
        /// <param name="departments"></param>
        /// <param name="sortType"></param>
        /// <returns></returns>
        private IQueryable<Department> SortList(IQueryable<Department> departments,string sortType)
        {
            switch (sortType)
            {
                case "DepartmentName":
                    return departments.OrderBy(d => d.DepartmentName);
                case "AddressLine":
                    return departments.OrderBy(d => d.Address.AddressLine);
                case "PostCode":
                    return departments.OrderBy(d => d.Address.Postcode);
                case "Contact":
                    return departments.OrderBy(d => d.Contact.WorkBase);
                case "DepartmentName DESC":
                    return departments.OrderByDescending(d => d.DepartmentName);
                case "AddressLine DESC":
                    return departments.OrderByDescending(d => d.Address.AddressLine);
                case "PostCode DESC":
                    return departments.OrderByDescending(d => d.Address.Postcode);
                case "Contact DESC":
                    return departments.OrderByDescending(d => d.Contact.WorkBase);
                default:
                    return departments;
            }
        }

        /// <summary>
        /// GetList method is a business method which is used to get a data list of department from database
        /// </summary>
        /// <param name="filter">filter</param>
        /// <param name="sort">sort</param>
        /// <param name="startRowIndex">startRowIndex</param>
        /// <param name="maximumRow">maximumRow</param>
        /// <returns>Departments</returns>
        public  IQueryable<Department> GetList(DepartmentFilter filter, string sort, int startRowIndex, int maximumRow)
        {
            var data = from d in _context.Departments
                       select d;

            // 1. Filter by condition
            if (filter != null)
            {
                data = FilterList(data, filter);
            }

            // 2. Sorting
            data = SortList(data, sort);

            // 3. Limit the rows
            data = data.Skip(startRowIndex).Take(maximumRow);
            return data;
        }

        /// <summary>
        /// The method is used to get number of record which is got from database
        /// </summary>
        /// <param name="filter">filter</param>
        /// <returns>Number of records</returns>
        public  int GetListCount(Commons.DataFilters.DepartmentFilter filter)
        {

            var data = from gor in _context.Departments
                       select gor;
            if (filter != null)
            {
                data = FilterList(data, filter);
            }
            return data.Count();
        }

        /// <summary>
        /// The method is used to mark a department record into In-Active status
        /// </summary>
        /// <param name="departmentId">departmentId</param>
        /// <returns>true if marking in-active successfully</returns>
        public  bool MarkInActive(int departmentId)
        {
            ServiceDBDataContext context = new ServiceDBDataContext();

            if(context.Departments.Any(d=>d.DepartmentId == departmentId))
            {
                context.Departments.Single(d=>d.DepartmentId == departmentId).IsActive = false;
                context.SubmitChanges();
                return true;
            }
            else
            {
                return false;   
            }
        }


        //-----------------------------vidt--------------

        public IQueryable<Department> ListDepartment()
        {

            return null;
        }
        /// <summary>
        /// Sets the department status.
        /// </summary>
        /// <param name="departmentId">The department id.</param>
        /// <param name="status">if set to <c>true</c> [status].</param>
        /// <returns>true/false</returns>
        public bool SetDepartmentStatus(int departmentId, bool status)
        {
            var department = _context.Departments.FirstOrDefault(o => o.DepartmentId == departmentId);
            if (department != null)
            {
                department.IsActive = status;
                return true;
            }
            return false;
        }
        /// <summary>
        /// Gets the department id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public Department GetDepartmentId(int id)
        {
            var department = _context.Departments.FirstOrDefault(g => g.DepartmentId == id);
            return department;
        }
        /// <summary>
        /// Adds the department.
        /// </summary>
        /// <param name="newDepartment">The new department.</param>
        /// <returns></returns>
        public bool AddDepartment(Department newDepartment)
        {
            try
            {
                using (var transaction = new TransactionScope())
                {
                    _context.Departments.InsertOnSubmit(newDepartment);
                    _context.SubmitChanges();
                    transaction.Complete();
                    return true;
                }
            }
            catch
            {

                return false;
            }
        }

        /// <summary>
        /// Edits the department.
        /// </summary>
        /// <param name="newDepartment">The new department.</param>
        /// <returns></returns>
        public bool EditDepartment(Department newDepartment)
        {
            var oldDepartment = _context.Departments.FirstOrDefault(d => d.DepartmentId == newDepartment.DepartmentId);
            if (oldDepartment != null)
            {
                oldDepartment.DepartmentName = newDepartment.DepartmentName;
                oldDepartment.ShortDescription = newDepartment.ShortDescription;
                oldDepartment.FullDescription = newDepartment.FullDescription;
                oldDepartment.CityTown = newDepartment.CityTown;

                oldDepartment.County = newDepartment.County;
                oldDepartment.CountryId = newDepartment.CountryId;
                oldDepartment.Fax = newDepartment.Fax;
                oldDepartment.PhoneNumber = newDepartment.PhoneNumber;
                oldDepartment.Email = newDepartment.Email;
                oldDepartment.WebAddress = newDepartment.WebAddress;
                oldDepartment.DirectorateId = newDepartment.DirectorateId;

                // Ref Key
                oldDepartment.BusinessType = newDepartment.BusinessId != null ? _context.BusinessTypes.FirstOrDefault(b => b.BusinessId == newDepartment.BusinessId) : null;
                oldDepartment.Address = newDepartment.AddressId != null ? _context.Addresses.FirstOrDefault(a => a.AddressId == newDepartment.AddressId) : null;
                oldDepartment.Contact = newDepartment.ContactId != null ? _context.Contacts.FirstOrDefault(a => a.ContactId == newDepartment.ContactId) : null;

                _context.SubmitChanges();
                return true;
            }
            return false;
        }
        /// <summary>
        /// Checks the name of the department.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        public bool CheckDepartmentName(string name)
        {
            var department = _context.Departments.FirstOrDefault(d => d.DepartmentName.Equals(name));
            return department != null;
        }
    }
}
